package Server.ExtComponents.MinaEngine.core;

import Server.ExtComponents.MinaEngine.config.MServerConfig;
import Server.ExtComponents.utilsKit.PriorityThreadFactory;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.transport.socket.SocketSessionConfig;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;


/**
 * @author :石头哥哥<br/>
 *         Project:FrameServer1.0
 *         Date: 13-5-19
 *         Time: 下午5:24
 */
public class MService {
    private static final Logger LOG = LoggerFactory.getLogger(MService.class);  //logger

    public MService(){}

    /**
     * Sets the handler which will handle all connections managed by this service.
     * 启动游戏服务器
     */
    public void startService() throws Exception {

       MServerConfig serverConfig=new MServerConfig();
       boolean status=serverConfig.IntiConfig();
       if (status){
           MServerIoHandler mServerIoHandler=new MServerIoHandler();

           /**given number of {@link org.apache.mina.transport.socket.nio.NioProcessor} for multithreading I/O operations.*/
           NioSocketAcceptor netAcceptor=new NioSocketAcceptor(MServerConfig.NioProcessor);

           IoBuffer.setUseDirectBuffer(false);
           netAcceptor.setReuseAddress(true);

           /***session config*/
           SocketSessionConfig sessionConfig=netAcceptor.getSessionConfig();
           sessionConfig.setReuseAddress(true);
           sessionConfig.setKeepAlive(true);
           sessionConfig.setTcpNoDelay(true);
        /*   关联在通道上的读、写或者是读写事件在指定时间内未发生，该通道就进入空
           闲状态。一旦调用这个方法，则每隔idleTime 都会回调过滤器、IoHandler 中的sessionIdle()
           方法。*/
           sessionConfig.setIdleTime(IdleStatus.READER_IDLE,
                   MServerConfig.SESSION_IDLE); //readTimeout

           /***filter chain config*/
           DefaultIoFilterChainBuilder chainBuilder=netAcceptor.getFilterChain();

           /**mina事件处理日志filter*/
//           LoggingFilter loggingFilter = new LoggingFilter();
//           loggingFilter.setExceptionCaughtLogLevel(LogLevel.WARN);
//           chainBuilder.addLast("logger",loggingFilter);

           chainBuilder.addLast("protocolCodecFilter",new ProtocolCodecFilter(new MServerProtocolCodecFactory()));//数据的编解码,IoProcessor 之后的第一个过滤器
          /* ExecutorFilter 的典型场景是将业务逻辑（譬如：耗时的数
           据库操作）放在单独的线程中运行，也就是说与IO 处理无关的操作可以考虑使用
           ExecutorFilter 来异步执行。*/
           chainBuilder.addLast("executors",new ExecutorFilter(MServerConfig.corePoolSize,2*MServerConfig.corePoolSize,MServerConfig.DEFAULT_KEEPALIVE_TIME, TimeUnit.SECONDS,new PriorityThreadFactory("executionHandlerThread",Thread.NORM_PRIORITY)));//业务处理线程池模型
           /***Handler，通过adapter接入了session的整个生命周期*/
           /**Sets the handler which will handle all connections managed by this service.*/
           netAcceptor.setHandler(mServerIoHandler);

           netAcceptor.bind(new InetSocketAddress(MServerConfig.GameServerPort));
           if (MServerConfig.DEBUG){
               LOG.info("server is started ,listening the port of:"+MServerConfig.GameServerPort);
           }
       }else {
           LOG.warn("startService failed!");
       }
    }

}
